package top.shen33.yang.base.aop;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.shen33.yang.base.validator.FormValidator;
import top.shen33.yang.base.validator.ValidatorException;
import top.shen33.yang.base.validator.ValidatorR;
import top.shen33.yang.base.validator.ValidatorUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * Created by Administrator on 2018-04-12.
 */
@Component
@Aspect
public class AopLog {


    private static final Logger log = LoggerFactory.getLogger(AopLog.class);


    @Pointcut("@annotation(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.stereotype.Controller)")
    private void myAspect() {


    }


    //    @Pointcut("@args(com.baomidou.springmvc.common.validator.FormValidator)")
    public void methodsParameter() {


    }

    @Around("execution(public * top.shen33.yang.controller.*.*(..))")

//    @Around("methodsParameter()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
//        log.info("Accepting beans with @FormValidator annotation: " + pjp.getArgs()[0]);

        Signature signature = pjp.getSignature();
        final String name = signature.getName();

        if (name.matches("do.*")) {

//            MethodSignature methodSignature = (MethodSignature)signature;
//            Method targetMethod = methodSignature.getMethod();
//            Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(name, targetMethod.getParameterTypes());

            Object[] arguments = pjp.getArgs();
            for (Object arg : arguments) {

                injectLogDate(arg);

//                System.out.println(JSON.toJSONString(arg));
                boolean annoFlag = arg.getClass().isAnnotationPresent(FormValidator.class);
                if (annoFlag) {
                    System.out.println("valid form data:" + arg);
                    ValidatorR r = ValidatorUtil.validIt(arg);

                    if (r.isErrFlag()) {
                        throw new ValidatorException(r.getErrMsg());
                    }
                }


            }

//            log.info("### "+realMethod);
        }


//        Annotation[][] parameterAnnotations = realMethod.getParameterAnnotations();
//        for (Annotation[] parameterAnnotation : parameterAnnotations) {
//            for (Annotation annotation : parameterAnnotation) {
//
//                if (annotation instanceof FormValidator){
//
//                    System.out.println("formValidator");
//                }
//            }
//        }


//        if(args!=null && args.length>0){
//
//            Object arg = args[0];
//
//
//        }

        Object object = pjp.proceed();
        return object;
    }

    private void injectLogDate(Object obj) {

        Date now = new Date();

        Method[] declaredMethods = obj.getClass().getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {

            String name = declaredMethod.getName();

            if ("setCdate".equals(name) || "setCtime".equals(name) || "setUtime".equals(name)) {

                try {
                    declaredMethod.invoke(obj, now);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            }
        }
    }


    /**
     * 获取request
     *
     * @return request
     */
    private HttpServletRequest getRequest() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }


}
